package cn.lili.modules.order.cart.render.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.lili.common.enums.ResultCode;
import cn.lili.common.exception.ServiceException;
import cn.lili.common.utils.CurrencyUtil;
import cn.lili.common.utils.StringUtils;
import cn.lili.modules.goods.client.GoodsClient;
import cn.lili.modules.goods.client.GrabOrderClient;
import cn.lili.modules.goods.entity.dos.Goods;
import cn.lili.modules.goods.entity.dos.GoodsSku;
import cn.lili.modules.goods.entity.vos.yunxin.BeforeCheckRes;
import cn.lili.modules.goods.entity.vos.yunxin.BeforeCheckVO;
import cn.lili.modules.goods.entity.vos.yunxin.SpuVO;
import cn.lili.modules.grab.GrabOrderParam;
import cn.lili.modules.grab.dingdong.reps.order.FreightCalcRespose;
import cn.lili.modules.grab.dingdong.res.order.FreightCalcRequest;
import cn.lili.modules.grab.xdxt.reps.order.OrderFreightPreviewReps;
import cn.lili.modules.grab.xdxt.res.order.OrderFreightPreviewReq;
import cn.lili.modules.member.entity.dos.UserAddress;
import cn.lili.modules.order.cart.entity.dto.TradeDTO;
import cn.lili.modules.order.cart.entity.enums.RenderStepEnums;
import cn.lili.modules.order.cart.entity.vo.CartSkuVO;
import cn.lili.modules.order.cart.render.CartRenderStep;
import cn.lili.modules.order.order.entity.dto.PriceDetailDTO;
import cn.lili.modules.order.order.service.OrderService;
import cn.lili.modules.system.client.RegionYbjClient;
import cn.lili.modules.system.entity.dos.RegionYbj;
import com.alibaba.fastjson.JSONObject;
import cn.lili.modules.system.client.RegionQddClient;
import cn.lili.modules.system.entity.dos.RegionQdd;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.shardingsphere.transaction.annotation.ShardingTransactionType;
import org.apache.shardingsphere.transaction.core.TransactionType;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import cn.lili.modules.system.client.RegionQddClient;
import cn.lili.modules.system.entity.dos.RegionQdd;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * 计算采购运费
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class GrabFreight implements CartRenderStep {

    @Resource
    private GoodsClient goodsClient;
    @Resource
    private GrabOrderClient grabOrderClient;
    @Resource
    private OrderService orderService;
    @Resource
    private HttpServletRequest request;
    @Resource
    private RegionQddClient regionQddClient;

    @Override
    public RenderStepEnums step() {
        return RenderStepEnums.SKU_GRAB_FREIGHT;
    }

    @Override
    public void render(TradeDTO tradeDTO) {
        //用户收货地址问题处理
        UserAddress userAddress = tradeDTO.getUserAddress();
        //如果收货地址为空，则抛出异常
        if (userAddress == null) {
            return;
        }
        //查询商品信息
        for (CartSkuVO cartSkuVO : tradeDTO.getSkuList()) {
            Goods goods = goodsClient.getById(cartSkuVO.getGoodsSku().getGoodsId());
            Double freightPrice = null;
            //壹邦玖运费计算
            if (null != goods.getThirdPartyPlatformType() && 1 == goods.getThirdPartyPlatformType()) {
                freightPrice = yiabngjiuFreightPrice(userAddress, goods, cartSkuVO); //设置运费
                cartSkuVO.getPriceDetailDTO().setFreightPrice(freightPrice);
            }
            //企叮咚运费计算
            if (null != goods.getThirdPartyPlatformType() && 2 == goods.getThirdPartyPlatformType()) {
                freightPrice = dingdongFreightPrice(userAddress, goods, cartSkuVO);
                //设置运费
                cartSkuVO.getPriceDetailDTO().setFreightPrice(freightPrice);
            }
            //盛创汇联计算
            if (null != goods.getThirdPartyPlatformType() && 3 == goods.getThirdPartyPlatformType()) {
                freightPrice = xdxtFreightPrice(userAddress, cartSkuVO);
                //设置运费
                cartSkuVO.getPriceDetailDTO().setFreightPrice(freightPrice);
            }


        }
    }

    /**
     * 壹邦玖运费计算
     */
    @Transactional
    @ShardingTransactionType(TransactionType.BASE)
    public Double yiabngjiuFreightPrice(UserAddress userAddress, Goods goods, CartSkuVO cartSkuVO) {
        BeforeCheckVO checkRes = new BeforeCheckVO();
        orderService.conversionAddress(checkRes, userAddress.getConsigneeAddressIdPath());

        checkRes.setPhone(userAddress.getMobile());
        checkRes.setConsignee(userAddress.getName());
        checkRes.setDescription(userAddress.getDetail());

        List<SpuVO> spuVOList = new ArrayList<>();
        //是壹邦玖的数据
        boolean goodsNotNull = cartSkuVO.getGoodsSku() != null;
        boolean isYiBangJiu = goodsNotNull && StringUtils.isNotEmpty(cartSkuVO.getGoodsSku().getThirdPartyPlatformId()) && Integer.valueOf(1).equals(cartSkuVO.getGoodsSku().getThirdPartyPlatformType());
        if (isYiBangJiu) {
            SpuVO spuVO = new SpuVO();
            spuVO.setNumber(cartSkuVO.getNum());
            spuVO.setSku(Long.valueOf(cartSkuVO.getGoodsSku().getThirdPartyPlatformId()));
            spuVOList.add(spuVO);
            goodsClient.addStorage(Integer.valueOf(cartSkuVO.getGoodsSku().getThirdPartyPlatformId()));
        }

        //选中的购物车里面，有壹邦玖的数据就进行一次下单前校验。
        if (CollectionUtil.isNotEmpty(spuVOList)) {
            checkRes.setSpuVOList(spuVOList);
            JSONObject jsonObject = orderService.beforeCheck(checkRes);
            if (jsonObject.getInteger("code") != 0) {
                log.error("jsonResult === {},  checkRes === {}", jsonObject.toJSONString(), JSONObject.toJSONString(checkRes));
                //checked 渲染购物车时不提示超出配送范围与手机号异常（因为可以修改），其他异常则不继续流程
                String msg = jsonObject.getString("msg");
                boolean checked = request.getRequestURI().contains("checked");
                boolean deliveryAddress = msg.contains("收货地址超出配送范围");
                boolean phone = msg.contains("手机号不符合格式");
                log.info("request.getRequestURI() =={}", request.getRequestURI());
                //渲染购物车时不校验地址与手机号
                if ((deliveryAddress || phone) && checked) {
                    return 0D;
                }
                //不是地址 与 手机号的问题就把商品下架掉。因为商品可能库存不足或其他原因
                if ((!deliveryAddress) && (!phone)) {
                    goodsClient.downGoods(goods.getId());
                    throw new ServiceException(ResultCode.APPID_ERROR, msg);
                }
                throw new ServiceException(ResultCode.APPID_ERROR, jsonObject.getString("msg"));
            }
            BeforeCheckRes beforeCheckRes = JSONObject.parseObject(JSONObject.toJSONString(jsonObject.get("data")), BeforeCheckRes.class);

            return CurrencyUtil.div(CurrencyUtil.convertDouble(beforeCheckRes.getFreight()),100);
        }
        return 0D;
    }

    /**
     * 盛创汇联运费计算
     * @param userAddress 地址
     * @param cartSkuVO 购物车
     * */
    public Double xdxtFreightPrice(UserAddress userAddress, CartSkuVO cartSkuVO){
        //地址
        String[] addressId = userAddress.getConsigneeAddressIdPath().split(",");
        String provinceId = addressId[0];
        String cityId = addressId[1];
        String areaId = addressId[2];
        RegionQdd province = regionQddClient.getRegionQddById(provinceId);
        RegionQdd city = regionQddClient.getRegionQddById(cityId);
        RegionQdd area = regionQddClient.getRegionQddById(areaId);

        //商品详情
        OrderFreightPreviewReq.OrderDetailsList detail = new OrderFreightPreviewReq.OrderDetailsList();
        detail.setCode(cartSkuVO.getGoodsSku().getThirdPartyPlatformId());
        detail.setNum(cartSkuVO.getNum());

        List<OrderFreightPreviewReq.OrderDetailsList> orderDetailsList = new ArrayList<>();
        orderDetailsList.add(detail);

        //商品
        OrderFreightPreviewReq orderFreightPreviewReq = new OrderFreightPreviewReq();
        orderFreightPreviewReq.setProvince(province.getRegionName());
        orderFreightPreviewReq.setCity(city.getRegionName());
        orderFreightPreviewReq.setDistrict(area.getRegionName());
        orderFreightPreviewReq.setAddressDetail(userAddress.getDetail());
        orderFreightPreviewReq.setOrderDetailsList(orderDetailsList);

        //发送计算运费请求
        OrderFreightPreviewReps orderFreightPreviewReps = grabOrderClient.xdxtFreightCalc(orderFreightPreviewReq);
        return orderFreightPreviewReps.getResult().getFreight();
    }

    /**
     * 企叮咚运费计算
     */
    public Double dingdongFreightPrice(UserAddress userAddress, Goods goods, CartSkuVO cartSkuVO) {
        //1.查询配送方式  默认配送方式 1
        String yf_mode = "1";
        String[] addressId = userAddress.getConsigneeAddressIdPath().split(",");
        String provinceId = addressId[0];
        String cityId = addressId[1];
        String areaId = addressId[2];
        RegionQdd province = regionQddClient.getRegionQddById(provinceId);
        RegionQdd city = regionQddClient.getRegionQddById(cityId);
        RegionQdd area = regionQddClient.getRegionQddById(areaId);



        //2.计算运费金额
        FreightCalcRequest freightCalcRequest = new FreightCalcRequest();
        freightCalcRequest.setProvince(province != null ? province.getRegionId() : null);
        freightCalcRequest.setCity(city != null ? city.getRegionId() : null);
        freightCalcRequest.setArea(area != null ? area.getRegionId() : null);
        freightCalcRequest.setGoods_id(goods.getThirdPartyPlatformId());
        freightCalcRequest.setNum(String.valueOf(cartSkuVO.getNum()));
        freightCalcRequest.setSpec_id(cartSkuVO.getGoodsSku().getThirdPartyPlatformId());
        freightCalcRequest.setYf_mode(yf_mode);
        FreightCalcRespose freightCalcRespose = grabOrderClient.freightCalc(freightCalcRequest);

        Double shipPrice = CurrencyUtil.div(CurrencyUtil.convertDouble(freightCalcRespose.getShip_price()), 100);
        return shipPrice;
    }
}
